#ifndef FILEDESCRIPTOR_H
#define FILEDESCRIPTOR_H

#include <Globals.h>
#include <File.h>
#include <Resource.h>

/**
  Syscall interface.
**/
namespace FileDescriptor_IF
{
  const int isValid     =0;
  const int close       =1;
  const int seek        =2;
  const int read        =3;
  const int write       =4;
  const int getFile     =5;
  const int getId       =6;
}

/**
   A file descriptor is an instantiation of a file object.
   It maintains state such as the offset in the file, and 
   read/write permissions.
**/
class FileDescriptor : public Callable
{
public:
  /**
     Mode types.
  **/
  enum ModeType
  {
    ReadOnly=1,
    WriteOnly,
    ReadWrite
  };
  enum Flags
  {
    Create=1,
    Append
  };
  enum SeekType
  {
    Set=0,
    Curr=1,
    End=2
  };
  
  /**
     Constructor. Nullifys stuff.
  **/
  FileDescriptor(char *filename, ModeType mode, Flags flags, s32int id=-1);
  
  ~FileDescriptor();

  /**
     Returns true if the descriptor is valid.
  **/
  bool isValid();
  
  /**
     Closes the file.
  **/
  void close();
  
  /**
     Seeks to a position in the file.
  **/
  u32int seek(u32int off, SeekType type);
  
  /**
     Reads from the file.
  **/
  u32int read(u32int length, u32int bufferResource);
  
  /**
     Writes to the file.
  **/
  u32int write(u32int length, u32int bufferResource);
  
  /**
    Gets the filedescriptor ID
  **/
  u32int getId();
  
  /**
    Creates a copy of this filedescriptor
  **/
  FileDescriptor *clone();
  
  /**
    Returns the file object this filedescriptor points at
  **/
  class File *getFile();
  u32int getFileResource();
  
  /**
    We are a system resource.
  **/
  Resource *resource;
  
private:
  /**
     The static file object that this filedescriptor is the
     instantiation of.
  **/
  class File *file;
  
  /**
     The current read/write offset in the file.
  **/
  u32int offset;
  
  /**
     The mode. (read/write)
  **/
  ModeType mode;

  /**
     The flags.
  **/
  Flags flags;
  
  /**
    The file descriptor number.
  **/
  u32int fd;
  
};



#endif // FILEDESCRIPTOR_H
